﻿using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.Web;
using System.IO;
//using SBS.Base;
using System;

namespace SBS.Common
{    
    /// <summary>
    /// 转换类
    /// </summary>
    public class Convert
    {
        /// <summary>
        /// 转换XML为HTML
        /// </summary>
        /// <param name="xmlstring">XML数据，可以是文件路径，也可以是XML字符串</param>
        /// <param name="xslpath">XSL 文件路径</param>
        /// <param name="param">转换过程接收的参数，Hashtable 将转换为 XsltArgumentList。</param>
        /// <returns>返回html字符串</returns>
        public static string xml2html(string xmlstring, string xslpath, Hashtable param, bool NoSysNode)
        {            
            return xml2html(xmlstring, GetXslProcessInMemory(xslpath), param, NoSysNode);
        }
        public static string xml2html(string xmlstring, XslCompiledTransform XslProcess, Hashtable param, bool NoSysNode)
        {
            

            //XmlReaderSettings xrsetting = new XmlReaderSettings();
            //xrsetting.ProhibitDtd = false;
            //xrsetting.XmlResolver = new XmlUrlResolver();
            //xrsetting.IgnoreComments = true;
            //xrsetting.IgnoreWhitespace = true;

           
            XmlDocument dom = new XmlDocument();

            if (xmlstring.Trim().Substring(0, 1) == "<")
            {
                dom.LoadXml(xmlstring);
            }
            else
            {
                dom.Load(xmlstring);
            }
            return xml2html(dom, XslProcess, param, NoSysNode);

            //if (HttpContext.Current != null && HttpContext.Current.Request.QueryString["output"] == "xml")
            //{
            //    HttpContext.Current.Response.ContentType = "text/xml";
            //    return dom.OuterXml;
            //}
            //if (NoSysNode != true)
            //{
            //    if (dom.DocumentElement.SelectSingleNode("system") != null)
            //    {
            //        dom.DocumentElement.RemoveChild(dom.DocumentElement.SelectSingleNode("system"));
            //    }
            //    dom.DocumentElement.AppendChild(GetSystemNode(dom));
            //}

            //if (HttpContext.Current != null)
            //{
            //    if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["debug"]) && HttpContext.Current.Request.QueryString["debug"] == "1")
            //    {
            //        HttpContext.Current.Response.ContentType = "text/xml";
            //        HttpContext.Current.Response.Write(dom.OuterXml);
            //        HttpContext.Current.Response.End();
            //        return "";
            //    }
            //}



            //XsltArgumentList argus = new XsltArgumentList();

            //if (param == null)
            //{
            //    param = new Hashtable();
            //}

            //if (HttpContext.Current != null)
            //{
            //    HttpCookie lang = HttpContext.Current.Request.Cookies["lang"];
            //    if (lang != null && !string.IsNullOrEmpty(lang.Value))
            //    {
            //        if (param.ContainsKey("dictionary"))
            //        {
            //            param["dictionary"] = Utility.GetLangDictionary(lang.Value);
            //        }
            //        else
            //        {
            //            param.Add("dictionary", Utility.GetLangDictionary(lang.Value));
            //        }
            //    }
            //    else
            //    {
            //        if (param.ContainsKey("dictionary"))
            //        {
            //            param["dictionary"] = Utility.GetLangDictionary("zh-cn");
            //        }
            //        else
            //        {
            //            param.Add("dictionary", Utility.GetLangDictionary("zh-cn"));
            //        }
            //    }
            //}
            //foreach (string key in param.Keys)
            //{
            //    if (key.Length > 4 && key.Substring(0, 4) == "urn:")
            //    {
            //        argus.AddExtensionObject(key, param[key]);
            //    }
            //    else
            //    {
            //        argus.AddParam(key, String.Empty, param[key]);
            //    }
            //}
            //XPathNavigator nav = dom.CreateNavigator();
            ////TextWriter html = new StringWriter();
            //MemoryStream ms = new MemoryStream();
            //XslProcess.Transform(nav, argus, ms);


            //ms.Position = 0;

            //StreamReader reader = new StreamReader(ms);
            //string result = reader.ReadToEnd();
            ////string result = html.ToString().Replace("<META http-equiv=\"Content-Type\" content=\"text/html; charset=utf-16\">", "");
            //reader.Close();
            //ms.Close();
            ////html.Close();

            //return result;
            
        }
        /// <summary>
        /// 转换XML为HTML
        /// </summary>
        /// <param name="dom">XmlDocument 对象</param>
        /// <param name="xslpath">XSL 文件路径</param>
        /// <param name="param">转换过程接收的参数，Hashtable 将转换为 XsltArgumentList。</param>
        /// <returns>返回html字符串</returns>            
        public static string xml2html(XmlDocument dom, string xslpath, Hashtable param, bool NoSysNode)
        {            
            return xml2html(dom, GetXslProcessInMemory(xslpath), param, NoSysNode);
        }
     
        public static string xml2html(XmlDocument dom, XslCompiledTransform XslProcess, Hashtable param, bool NoSysNode)
        {
            if (HttpContext.Current != null && HttpContext.Current.Request.QueryString["output"] == "xml")
            {
                HttpContext.Current.Response.ContentType = "text/xml";
                return dom.OuterXml;
            }
            
            if (NoSysNode != true)
            {
                if (dom.DocumentElement.SelectSingleNode("system") != null)
                {
                    dom.DocumentElement.RemoveChild(dom.DocumentElement.SelectSingleNode("system"));
                }
                //dom.DocumentElement.AppendChild(XmlTransform.CreateSystemElement(dom));
                dom.DocumentElement.AppendChild(GetSystemNode(dom));
            }
           
            if (HttpContext.Current != null)
            {
                if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["debug"]) && HttpContext.Current.Request.QueryString["debug"] == "1")
                {
                    HttpContext.Current.Response.ContentType = "text/xml";
                    HttpContext.Current.Response.Write(dom.OuterXml);
                    HttpContext.Current.Response.End();
                    return "";
                }
            }
            if (HttpContext.Current != null)
            {
                HttpCookie lang = HttpContext.Current.Request.Cookies["lang"];
                string langTxt = (lang != null && !string.IsNullOrEmpty(lang.Value)) ? lang.Value : "zh-cn";
                if (param == null)
                {
                    param = new Hashtable();
                }
                if (!param.ContainsKey("dictionary"))
                {
                    param.Add("dictionary", Utility.GetLangDictionary(langTxt));
                }
            }
            XmlTransform Xt = new XmlTransform();
            Xt.InputXmlNode = dom;
            Xt.InputXslt = XslProcess;
            Xt.Argus = param;
            return Xt.TransformToString();


            //XsltArgumentList argus = new XsltArgumentList();

            //if (param == null)
            //{
            //    param = new Hashtable();
            //}

            //if (HttpContext.Current != null)
            //{
            //    HttpCookie lang = HttpContext.Current.Request.Cookies["lang"];
            //    if (lang != null && !string.IsNullOrEmpty(lang.Value))
            //    {
            //        if (param.ContainsKey("dictionary"))
            //        {
            //            param["dictionary"] = Utility.GetLangDictionary(lang.Value);
            //        }
            //        else
            //        {
            //            param.Add("dictionary", Utility.GetLangDictionary(lang.Value));
            //        }
            //    }
            //    else
            //    {
            //        if (param.ContainsKey("dictionary"))
            //        {
            //            param["dictionary"] = Utility.GetLangDictionary("zh-cn");
            //        }
            //        else
            //        {
            //            param.Add("dictionary", Utility.GetLangDictionary("zh-cn"));
            //        }
            //    }
            //}

            //foreach (string key in param.Keys)
            //{
            //    if (key.Length > 4 && key.Substring(0, 4) == "urn:")
            //    {
            //        argus.AddExtensionObject(key, param[key]);
            //    }
            //    else
            //    {
            //        argus.AddParam(key, String.Empty, param[key]);
            //    }
            //}

            //XPathNavigator nav = dom.CreateNavigator();
            //MemoryStream ms = new MemoryStream();
            //XslProcess.Transform(nav, argus, ms);

            //ms.Position = 0;
            //StreamReader reader = new StreamReader(ms);
            //string html = reader.ReadToEnd();
            //reader.Close();
            //ms.Close();
            //return html;

        }
        /// <summary>
        /// 转换XML为HTML
        /// </summary>
        /// <param name="xmlstring">XML数据，可以是文件路径，也可以是XML字符串</param>
        /// <param name="xslpath">XSL 文件路径</param>
        /// <returns>返回html字符串</returns>
        public static string xml2html(XmlDocument dom, string xslpath)
        {
            return xml2html(dom, xslpath, null, false);
        }
        public static string xml2html(XmlDocument dom, string xslpath, Hashtable param)
        {
            return xml2html(dom, xslpath, param, false);
        }
        public static string xml2html(string xmlstring, string xslpath)
        {
            return xml2html(xmlstring, xslpath, null, false);
        }
        public static string xml2html(string xmlstring, string xslpath, bool NoSysNode)
        {
            return xml2html(xmlstring, xslpath, null, NoSysNode);
        }
        public static string xml2html(string xmlstring, string xslpath, Hashtable param)
        {
            return xml2html(xmlstring, xslpath, param, false);
        }

        public static string xml2html(XPathNavigator nav, string xslcode, Hashtable param)
        {
            XmlReaderSettings xrsetting = new XmlReaderSettings();
            xrsetting.ProhibitDtd = false;
            xrsetting.XmlResolver = new XmlUrlResolver();
            xrsetting.IgnoreComments = true;
            xrsetting.IgnoreWhitespace = true;

            StringReader sr = new StringReader(xslcode);

            XmlReader xr = XmlReader.Create(sr, xrsetting);
            
            XslCompiledTransform process = new XslCompiledTransform();

            XsltSettings setting = XsltSettings.TrustedXslt;
            setting.EnableDocumentFunction = true;
            setting.EnableScript = true;

            XmlUrlResolver resolver = new XmlUrlResolver();
            resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

            XsltArgumentList argus = new XsltArgumentList();
            foreach (string key in param.Keys)
            {
                if (key.Length > 4 && key.Substring(0, 4) == "urn:")
                {
                    argus.AddExtensionObject(key, param[key]);
                }
                else
                {
                    argus.AddParam(key, String.Empty, param[key]);
                }
            }

            try
            {
                process.Load(xr, setting, resolver);
                TextWriter html = new StringWriter();
                
                process.Transform(nav, argus, html);
                return html.ToString();
            }
            catch (Exception ex)
            {
                return null;
            }
            finally
            {
                xr.Close();
            }
        }

        public static string xml2text(string xmlstring, string xslpath, Hashtable param, bool NoSysNode)
        {
            return xml2html(xmlstring, xslpath, param, true);
        }
        public static string xml2text(string xmlstring, string xslpath)
        {
            return xml2html(xmlstring, xslpath, null, true);
        }        
        public static string xml2text(XmlDocument dom, string xslpath, Hashtable param, bool NoSysNode)
        {
            return xml2html(dom, xslpath, param, true);
        }
        public static string xml2text(XmlDocument dom, string xslpath)
        {
            return xml2html(dom, xslpath, null, true);
        }
        public static string xml2text(XmlDocument dom, string xslpath, bool NoSysNode)
        {
            return xml2html(dom, xslpath, null, NoSysNode);
        }
        public static XmlNode GetSystemNode(XmlDocument dom)
        {
            XmlElement sys = dom.CreateElement("system");
            XmlElement url = dom.CreateElement("url");
            XmlElement http = dom.CreateElement("http");
            XmlElement cookies = dom.CreateElement("cookies");
            XmlElement variable = dom.CreateElement("variable");

            if (HttpContext.Current != null)
            {
                foreach (string key in HttpContext.Current.Request.QueryString)
                {

                    if (key != null && key.Length > 0 && "0123456789".IndexOf(key.Substring(0, 1)) == -1)
                    {
                        try
                        {
                            if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString[key]))
                            {
                                url.SetAttribute(key.ToLower(), HttpContext.Current.Request.QueryString[key]);
                            }
                            else
                            {
                                url.SetAttribute(key.ToLower(), "");
                            }

                        }
                        catch (Exception ex)
                        {
                            //随机数显示有问题
                        }
                    }
                }

                foreach (string key in HttpContext.Current.Request.Cookies.AllKeys)
                {

                    if (key != null && key.Length > 0 && "0123456789".IndexOf(key.Substring(0, 1)) == -1)
                    {
                        XmlAttribute attr = dom.CreateAttribute(key);

                        if (key == "timezone")
                        {
                            attr.Value = HttpContext.Current.Request.Cookies[key].Value;
                        }
                        else
                        {
                            attr.Value = HttpContext.Current.Server.UrlDecode(HttpContext.Current.Request.Cookies[key].Value);
                        }
                        cookies.SetAttributeNode(attr);
                    }
                }
            }
            if (HttpContext.Current != null && HttpContext.Current.Request.UserLanguages != null)
            {
                variable.SetAttribute("lang", string.Join(",", HttpContext.Current.Request.UserLanguages));
            }
            variable.SetAttribute("servertime", SBS.Common.Utility.GetNowTime());
            http.AppendChild(cookies);
            http.AppendChild(variable);
            sys.AppendChild(url);
            sys.AppendChild(http);
            return sys;
        }
        //private static XslCompiledTransform GetXslProcessInMemory(string xslkey)
        //{
        //    string LastWriteTime = File.GetLastWriteTime(xslkey).ToString("yyyy-MM-ddTHH:mm:ss.fffK");
        //    string key = LastWriteTime + xslkey;

        //    if (HttpContext.Current.Application[LastWriteTime + xslkey] == null || HttpContext.Current.Request.QueryString["debug"] == "3")
        //    {
        //        XmlReaderSettings xrsetting = new XmlReaderSettings();
        //        xrsetting.ProhibitDtd = false;
        //        xrsetting.XmlResolver = new XmlUrlResolver();
        //        xrsetting.IgnoreComments = true;
        //        xrsetting.IgnoreWhitespace = true;

        //        XmlReader xr = XmlReader.Create(xslkey, xrsetting);
        //        XslCompiledTransform process = new XslCompiledTransform();

        //        XsltSettings setting = XsltSettings.TrustedXslt;
        //        setting.EnableDocumentFunction = true;
        //        setting.EnableScript = true;

        //        XmlUrlResolver resolver = new XmlUrlResolver();
        //        resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

        //        try
        //        {
        //            process.Load(xr, setting, resolver);
        //        }
        //        catch (Exception ex)
        //        {
        //            return null;
        //        }
        //        finally
        //        {
        //            xr.Close();
        //        }

        //        string[] removeKey = new string[HttpContext.Current.Application.AllKeys.Length];
        //        int i = 0;
        //        foreach (string appkey in HttpContext.Current.Application.AllKeys)
        //        {
        //            if (appkey.Length <= 29) continue;
        //            if (appkey.Substring(29) == xslkey)
        //            {
        //                removeKey[i++] = appkey;
        //            }
        //        }
        //        HttpContext.Current.Application.Lock();
        //        foreach (string k in removeKey)
        //        {
        //            HttpContext.Current.Application.Remove(k);
        //        }
        //        HttpContext.Current.Application.UnLock();

        //        HttpContext.Current.Application[LastWriteTime + xslkey] = process;
        //    }
        //    return (XslCompiledTransform)HttpContext.Current.Application[LastWriteTime + xslkey];
        //}
        public static XslCompiledTransform GetXslProcessInMemory(string xslkey)
        {
            return XmlTransform.GetXslProcessInMemory(xslkey);
            /////////////////////////////////////////////////////////////////


            //if (HttpRuntime.Cache[xslkey] != null)
            //{
            //    //return (XslCompiledTransform)HttpRuntime.Cache[xslkey];
            //}

            //XmlReaderSettings xrsetting = new XmlReaderSettings();
            //xrsetting.ProhibitDtd = false;
            //xrsetting.XmlResolver = new XmlUrlResolver();
            //xrsetting.IgnoreComments = true;
            //xrsetting.IgnoreWhitespace = true;

            //XmlReader xr = XmlReader.Create(xslkey, xrsetting);
            //XslCompiledTransform process = new XslCompiledTransform();

            //XsltSettings setting = XsltSettings.TrustedXslt;
            //setting.EnableDocumentFunction = true;
            //setting.EnableScript = true;

            //XmlUrlResolver resolver = new XmlUrlResolver();
            //resolver.Credentials = System.Net.CredentialCache.DefaultCredentials;

            //try
            //{
            //    process.Load(xr, setting, resolver);
            //}
            //catch (Exception ex)
            //{
            //    return null;
            //}
            //finally
            //{
            //    xr.Close();
            //}

            //System.Web.Caching.CacheDependency dep = new System.Web.Caching.CacheDependency(xslkey);
            //HttpRuntime.Cache.Insert(xslkey, process, dep);
            //return (XslCompiledTransform)HttpRuntime.Cache[xslkey];

        }
    }    

}
